﻿using System;
using System.Collections.Generic;
using System.Reflection;
using Autofac;
using Castle.DynamicProxy;
using Microsoft.AspNetCore.Routing;
using Module = Autofac.Module;

namespace ZilLion.Service.Core.Ioc
{
    /// <summary>
    ///     模块Loader基类
    /// </summary>
    public abstract class ComponentLoaderBase : Module, IComponentLoader
    {
        private Assembly _assembly;
        protected ContainerBuilder Builder { get; set; }

        public void SetComponentAssembly(Assembly assembly)
        {
            _assembly = assembly;
        }


        public void RegisterWebSocketHandle()
        {
            foreach (var type in _assembly.GetExportedTypes())

            {
                if (type.GetTypeInfo().BaseType.Name == "WebSocketHandler")
                {
                    RegisterTypeSingleInstance(type);
                    WebSocketHandlTypes.Add(type);
                }
               
            }
        }


        public void RegisterWebSocketHandleStrategy()
        {
            foreach (var type in _assembly.GetExportedTypes())

            {
                if (type.GetTypeInfo().GetInterface("IMessageHandleStrategy") != null)
                {
                    RegisterTypePerDependency(type);
                    WebSocketHandlStrategyTypes.Add(type);
                }
               
            }
        }

        public virtual void ConfigureSpecialRoute(IRouteBuilder routeBuilder)
        {
        }


        public virtual Dictionary<string, string> InterceptJwtpayload(Dictionary<string, string> formpayload)
        {
            return formpayload;
        }

        public IList<Type> WebSocketHandlTypes { get; private set; }=new List<Type>();
        public IList<Type> WebSocketHandlStrategyTypes { get; private set; } = new List<Type>();

        /// <summary>
        ///     注册组件
        /// </summary>
        /// <param name="builder"></param>
        public virtual void Register(ContainerBuilder builder)
        {
            Builder = builder;
            if (_assembly == null) _assembly = Assembly.GetExecutingAssembly();
            RegisterWebSocketHandle();
            RegisterWebSocketHandleStrategy();
        }


        protected override void Load(ContainerBuilder builder)
        {
            Register(builder);
        }

        #region 注册泛型

        /// <summary>
        ///     注册泛型
        /// </summary>
        public void RegisterTypePerDependencyWithGeneric(Type instancetype, Type interfacetype,
            Type interceptorType = null)
        {
            if (TypeIsInterceptor(interceptorType))
                Builder.RegisterGeneric(instancetype)
                    .As(interfacetype)
                    .InstancePerDependency();
            //todo aop
            //.EnableInterfaceInterceptors()
            //.InterceptedBy(interceptorType);
            else
                Builder.RegisterGeneric(instancetype).As(interfacetype).InstancePerDependency();
        }

        #endregion

        /// <summary>
        ///     判断interceptorType 是否为Castle.DynamicProxy.IInterceptor
        /// </summary>
        /// <param name="interceptorType"></param>
        /// <returns></returns>
        private static bool TypeIsInterceptor(Type interceptorType)
        {
            return interceptorType != null && interceptorType.GetInterfaces().ContainsAny(typeof(IInterceptor));
        }

        #region 注册程序集

        /// <summary>
        ///     注册程序集(类型注册成对应接口)
        /// </summary>
        /// <param name="parameters"></param>
        public void RegisterAssemblis(params Assembly[] parameters)
        {
            Builder.RegisterAssemblyTypes(parameters)
                .AsImplementedInterfaces();
        }

        /// <summary>
        ///     注册程序集
        /// </summary>
        /// <param name="parameters"></param>
        public void RegisterAssemblisWithAop<T>(params Assembly[] parameters) where T : IInterceptor
        {
            Builder.RegisterAssemblyTypes(parameters)
                .AsImplementedInterfaces();
            //todo aop
            //  .EnableInterfaceInterceptors()
            //.InterceptedBy(typeof(T));
        }

        #endregion

        #region 注册单例

        /// <summary>
        ///     注册成单例
        /// </summary>
        public void RegisterTypeSingleInstance(Type instanceType, Type interceptorType = null)
        {
            if (TypeIsInterceptor(interceptorType))
                Builder.RegisterType(instanceType).SingleInstance();
            //todo aop
            //  .EnableInterfaceInterceptors()
            //.InterceptedBy(typeof(T));
            else
                Builder.RegisterType(instanceType).SingleInstance();
        }

        /// <summary>
        ///     注册成单例
        /// </summary>
        public void RegisterTypeSingleInstance(Type instanceType, Type interfaceType, Type interceptorType = null)
        {
            if (TypeIsInterceptor(interceptorType))
                Builder.RegisterType(interfaceType).As(interfaceType).SingleInstance();
            //todo aop
            //  .EnableInterfaceInterceptors()
            //.InterceptedBy(typeof(T));
            else
                Builder.RegisterType(interfaceType).As(interfaceType).SingleInstance();
        }

        /// <summary>
        ///     注册成单例为接口
        /// </summary>
        /// <typeparam name="TLt"></typeparam>
        /// <typeparam name="T"></typeparam>
        public void RegisterTypeSingleInstance<TLt, T>(Type interceptorType = null) where TLt : T
        {
            if (TypeIsInterceptor(interceptorType))
                Builder.RegisterType<TLt>()
                    .As<T>()
                    .SingleInstance();
            //todo aop
            //  .EnableInterfaceInterceptors()
            //.InterceptedBy(typeof(T));
            else
                Builder.RegisterType<TLt>().As<T>().SingleInstance();
        }

        /// <summary>
        ///     单例注册
        /// </summary>
        /// <typeparam name="TLt"></typeparam>
        public void RegisterTypeSingleInstance<TLt>(Type interceptorType = null)
        {
            if (TypeIsInterceptor(interceptorType))
                Builder.RegisterType<TLt>().SingleInstance();
            //todo aop
            //  .EnableInterfaceInterceptors()
            //.InterceptedBy(typeof(T));
            else
                Builder.RegisterType<TLt>().SingleInstance();
        }

        #endregion

        #region 注册瞬态

        /// <summary>
        ///     瞬态注册为接口
        /// </summary>
        /// <typeparam name="TLt"></typeparam>
        /// <typeparam name="T"></typeparam>
        public void RegisterTypePerDependency<TLt, T>(Type interceptorType = null) where TLt : T
        {
            if (TypeIsInterceptor(interceptorType))
                Builder.RegisterType<TLt>()
                    .As<T>()
                    .InstancePerDependency();
            //todo aop
            //  .EnableInterfaceInterceptors()
            //.InterceptedBy(typeof(T));
            else
                Builder.RegisterType<TLt>().As<T>().InstancePerDependency();
        }

        /// <summary>
        ///     瞬态注册
        /// </summary>
        /// <typeparam name="TLt"></typeparam>
        public void RegisterTypePerDependency<TLt>(Type interceptorType = null)
        {
            if (TypeIsInterceptor(interceptorType))
                Builder.RegisterType<TLt>()
                    .InstancePerDependency();
            //todo aop
            //  .EnableInterfaceInterceptors()
            //.InterceptedBy(typeof(T));
            else
                Builder.RegisterType<TLt>().InstancePerDependency();
        }

        /// <summary>
        ///     瞬态注册
        /// </summary>
        public void RegisterTypePerDependency(Type instanceType, Type interceptorType = null)
        {
            if (TypeIsInterceptor(interceptorType))
                Builder.RegisterType(instanceType)
                    .InstancePerDependency();
            //todo aop
            //  .EnableInterfaceInterceptors()
            //.InterceptedBy(typeof(T));
            else
                Builder.RegisterType(instanceType).InstancePerDependency();
        }

        /// <summary>
        ///     瞬态注册(并且给类型加上Ket)
        /// </summary>
        public void RegisterTypePerDependency(Type instanceType, string serviceName)
        {
            Builder.RegisterType(instanceType).Named(serviceName, instanceType).InstancePerDependency();
        }

        #endregion

        #region 注册为受Lifetime管理

        /// <summary>
        ///     注册为受Lifetime管理 实例
        /// </summary>
        /// <typeparam name="TLt"></typeparam>
        /// <typeparam name="T"></typeparam>
        public void RegisterTypePerLifetimeScope<TLt, T>(Type interceptorType = null) where TLt : T
        {
            if (TypeIsInterceptor(interceptorType))
                Builder.RegisterType<TLt>()
                    .As<T>()
                    .InstancePerLifetimeScope();
            //todo aop
            //  .EnableInterfaceInterceptors()
            //.InterceptedBy(typeof(T));
            else

                Builder.RegisterType<TLt>()
                    .As<T>()
                    .InstancePerLifetimeScope();
        }

        /// <summary>
        ///     注册为受Lifetime管理 实例
        /// </summary>
        /// <typeparam name="T"></typeparam>
        public void RegisterTypePerLifetimeScope<T>(Type interceptorType = null)
        {
            if (TypeIsInterceptor(interceptorType))
                Builder.RegisterType<T>()
                    .InstancePerLifetimeScope();
            //todo aop
            //  .EnableInterfaceInterceptors()
            //.InterceptedBy(typeof(T));
            else
                Builder.RegisterType<T>().InstancePerLifetimeScope();
        }

        #endregion
    }
}